const PORT = 7777
const WebSocket = require("ws");
const MpegMuxer = require("./mpeg-converter");
const querystring = require('querystring')
const debug = require("debug")("rtsp-server");
const url = require("url");
const wss = new WebSocket.Server({ port: PORT});

CLIENTS = {};
PROC = {};
PROC_LRU = {};
THRESHOLD = 16;



wss.on("connection", (ws, req) =>{
    var name = url.parse(req.url).pathname;
    var arg = url.parse(req.url).query;
    var params = querystring.parse(arg);
    var rtspAddr = params.addr;
    var display =  params.method;
    if(!name || !arg || !rtspAddr){
        debug(`requested url ${req.url} is error`);
        return;
    }
    else
        debug(`requested url is ${req.url}`);

    
    if (! (rtspAddr in CLIENTS)){
        debug("client for new channel");
        CLIENTS[rtspAddr] = [ws]
        //create a child_process to convert video type
        var muxer = new MpegMuxer({id: name , url: rtspAddr, display: display});
        PROC[rtspAddr] = muxer;
        muxer.on(name + "-data", (data) =>{
            CLIENTS[rtspAddr] =  CLIENTS[rtspAddr].filter((ele) => ele.readyState === WebSocket.OPEN)
            CLIENTS[rtspAddr].forEach((client) =>{
                    client.send(data);
            });
        });
        muxer.on(name + "-error", (err) => {
            debug(`the error happend for ${name} : ${err}`)
        });
        muxer.on(name + "-output", (output) => {
            debug(`the output for ${name} : ${output}`)
        })

    }
    else {
        debug("client for existing channel");
        CLIENTS[rtspAddr].push(ws);
    }
    ws.on("close", ()=>{
            debug("connection is closed");
            CLIENTS[rtspAddr] =  CLIENTS[rtspAddr].filter((ele) => ele.readyState === WebSocket.OPEN)
            //close no connected process
            Object.keys(CLIENTS).forEach((rtsp) =>{
                if(Object.keys(CLIENTS).length > THRESHOLD && CLIENTS[rtsp].length === 0 ){
                    debug("there are no socket listening " + rtsp);
                    PROC[rtsp].stream.stdout.end();
                    PROC[rtsp].stream.kill();
                    PROC[rtsp].destroy();
                    delete PROC[rtsp];
                    delete CLIENTS[rtsp];
                }

            });
    });
    ws.on('error', (err)=>{
            debug(`${err} happened for connection`);
    });

});

